package com.agent.user.service;

import com.agent.common.constant.CommonConstants;
import com.agent.common.entity.UserContext;
import com.agent.common.exception.AuthenticationException;
import com.agent.common.exception.BusinessException;
import com.agent.common.result.ResultCode;
import com.agent.common.utils.IdGenerator;
import com.agent.user.entity.User;
import com.agent.user.mapper.UserMapper;
import com.agent.user.utils.PasswordUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;

/**
 * 用户服务实现
 *
 * @author Jeff_Wan
 * @description 处理用户核心业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserMapper userMapper;
    private final IdGenerator idGenerator = IdGenerator.getInstance();

    /**
     * 通过Google ID创建或更新用户
     *
     * @param googleId  Google账号ID
     * @param email     邮箱
     * @param username  用户名
     * @param avatarUrl 头像URL
     * @return 创建/更新后的用户对象
     */
    @Transactional
    public User createOrUpdateByGoogleId(String googleId, String email, String username, String avatarUrl) {
        Optional<User> existingUser = Optional.ofNullable(userMapper.selectByGoogleId(googleId));
        if (existingUser.isPresent()) {
            User user = existingUser.get();
            user.setEmail(email);
            user.setUsername(username);
            user.setAvatarUrl(avatarUrl);
            userMapper.updateById(user);
            return user;
        } else {
            // 新增用户
            User newUser = new User();
            newUser.setId(idGenerator.nextId());
            newUser.setGoogleId(googleId);
            newUser.setEmail(email);
            newUser.setUsername(username);
            newUser.setAvatarUrl(avatarUrl);
            newUser.setMembershipType(CommonConstants.MEMBER_FREE);
            userMapper.insert(newUser);

            // 新用户赠送积分
//            grantNewUserBonus(newUser.getId());

            return newUser;
        }
    }

    /**
     * 用户注册
     * @param email 邮箱
     * @param password 密码
     * @return 用户ID
     */
    @Transactional
    public Long register(String email, String password) {
        // 检查邮箱是否已注册
        User existingAuth = userMapper.findByIdentifierAndType(email, "EMAIL");
        if (existingAuth != null) {
            throw new AuthenticationException(ResultCode.INVALID_CREDENTIALS, "Email already registered");
        }

        // 创建用户认证记录
        User user = new User();
        user.setId(IdGenerator.getInstance().nextId());
        user.setEmail(email);
        user.setPassword(PasswordUtils.encode(password));
        user.setCreatedAt(LocalDateTime.now());
        userMapper.insert(user);
        return user.getId();
    }

    /**
     * 通过用户ID获取用户信息
     *
     * @param userId 用户ID
     * @return 用户对象
     */
    public User getUserById(Long userId) {
        return userMapper.selectById(userId);
    }

    /**
     * 获取用户上下文信息
     *
     * @param userId 用户ID
     * @return 用户上下文对象
     */
    public UserContext getUserContext(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST);
        }

        UserContext context = new UserContext();
        context.setUserId(user.getId());
        context.setUsername(user.getUsername());
        context.setMembershipType(user.getMembershipType());
        context.setSubscriptionType(user.getSubscriptionType());
        context.setAvatarUrl(user.getAvatarUrl());
        context.setEmail(user.getEmail());

        // 计算剩余积分
//        context.setRemainingCredits(userCreditMapper.getTotalValidCredits(userId));

        // 检查会员状态
//        checkMembershipStatus(user, context);

        return context;
    }

    /**
     * 检查并更新会员状态
     *
     * @param user    用户对象
     * @param context 用户上下文
     */
    private void checkMembershipStatus(User user, UserContext context) {
        if (user.getSubscriptionEndDate() != null &&
                user.getSubscriptionEndDate().isBefore(LocalDateTime.now())) {
            // 会员已过期，降级为免费用户
            context.setMembershipType(CommonConstants.MEMBER_FREE);
            context.setSubscriptionType(null);

            // 更新数据库
            user.setMembershipType(CommonConstants.MEMBER_FREE);
            user.setSubscriptionType(null);
            user.setSubscriptionStartDate(null);
            user.setSubscriptionEndDate(null);
            userMapper.updateById(user);
        }
    }

    /**
     * 更新会员信息
     *
     * @param userId           用户ID
     * @param membershipType   会员类型
     * @param subscriptionType 订阅类型
     */
    @Transactional
    public void updateMembership(Long userId, String membershipType, String subscriptionType, LocalDateTime startDate, LocalDateTime endDate) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST);
        }
        userMapper.updateMembership(
                userId,
                membershipType,
                subscriptionType,
                startDate,
                endDate
        );

        // 发放订阅积分
//        grantSubscriptionCredits(userId, membershipType, subscriptionType);
    }

    /**
     * 计算订阅到期时间
     *
     * @param startDate        开始时间
     * @param subscriptionType 订阅类型
     * @return 到期时间
     */
    private LocalDateTime calculateExpiryDate(LocalDateTime startDate, String subscriptionType) {
        if (CommonConstants.SUBSCRIPTION_YEARLY.equals(subscriptionType)) {
            return startDate.plus(365, ChronoUnit.DAYS);
        } else {
            return startDate.plus(30, ChronoUnit.DAYS);
        }
    }

    public User getUserByEmail(String email) {
        return userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getEmail, email).last("limit 1"));
    }

    public User getUserByUsername(String username) {
        return userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username).last("limit 1"));
    }
}